import java.util.ArrayList;
import java.beans.XMLDecoder;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import com.generationjava.io.WritingException;
import com.generationjava.io.xml.XmlWriter;

public class Kysimused {

	private ArrayList<Integer> vastatud_kysimuste_nrd = new ArrayList<Integer>();
	private ArrayList<Kysimus> kysimused = new ArrayList<Kysimus>();
	private String teema;
	
	public Kysimus getNextSuvaKyss() {
		ArrayList<Integer> lubatudIndexid = new ArrayList<Integer>();
		for (int i = 0; i < this.kysimused.size(); i++) {
			if (!kas_juba_kysitud(new Integer(i))) {
				lubatudIndexid.add(new Integer(i));
			}
		}

		if (lubatudIndexid.size() == 0) {
			System.out.println("Küsimused otsas, hakkame kordama..");
			vastatud_kysimuste_nrd = new ArrayList<Integer>();
			int random_nr = (int) (Math.random() * this.kysimused.size());
			vastatud_kysimuste_nrd.add(new Integer(random_nr));
			return this.kysimused.get(random_nr);
		}
		
		int random_nr = (int) (Math.random() * lubatudIndexid.size());
		Integer kysimuse_nr = lubatudIndexid.get(random_nr);
		vastatud_kysimuste_nrd.add(kysimuse_nr);
		return this.kysimused.get(kysimuse_nr.intValue());
	}

	private boolean kas_juba_kysitud(Integer kontrolli_numbrit) {
		for (int i = 0; i < this.vastatud_kysimuste_nrd.size(); i++) {
			if (this.vastatud_kysimuste_nrd.get(i).equals(kontrolli_numbrit)) {
				return true;
			}
		}
		return false;
	}

	

	public void setKysimused(ArrayList<Kysimus> kyssad) {
		this.kysimused = kyssad;
	}

	public ArrayList<Kysimus> get_Kysimused() {
		return this.kysimused;
	}

	public Kysimused(boolean add_examples) {
		
		setTeema("Uus_teema");

		// siin loadime ajutiselt manuaalselt mõned testiküsimused
		// tulevikus peaks küsimuste sisselugemine toimuma failidest

		if (add_examples) {
			Kysimus uus_kysimus = new Kysimus();

			uus_kysimus.set_kysimus("Millised nendest kulutustest arvestatakse SKP arvutamisel ja millisesse kululahtrisse need sobiksid?");
			uus_kysimus.setKysimuse_pilt("rat.gif");
			Vastus uus_vastus = new Vastus();
			uus_vastus.setVastus_kasoige(true);
			uus_vastus.setVastusepilt("cow.gif");
			uus_vastus.setVastuse_text("prantslased ostsid Raekoja platsi jaapani restoranist sushit ");
			uus_kysimus.add_vastus(uus_vastus);

			uus_vastus = new Vastus();
			uus_vastus.setVastus_kasoige(false);
			uus_vastus.setVastusepilt("cow.gif");
			uus_vastus.setVastuse_text("kirjandusmuuseum ostis antikvariaadist Läti Hendriku autogrammiga Liivimaa Kroonika");
			uus_kysimus.add_vastus(uus_vastus);

			uus_vastus = new Vastus();
			uus_vastus.setVastus_kasoige(false);
			uus_vastus.setVastusepilt("bat.gif");
			uus_vastus.setVastuse_text("klient ostis väga väikese läbisõiduga kasutatud auto");
			uus_kysimus.add_vastus(uus_vastus);

			uus_vastus = new Vastus();
			uus_vastus.setVastus_kasoige(false);
			uus_vastus.setVastusepilt("monkey.gif");
			uus_vastus.setVastuse_text("klient ostis kinnisvaraarendajatelt renoveeritud maja Nõmme linnaosas");
			uus_kysimus.add_vastus(uus_vastus);

			add_kysimus(uus_kysimus);

			uus_kysimus = new Kysimus();
			uus_kysimus.set_kysimus("Viletsuse e. diskomfordi indeks on:");
			uus_kysimus.setKysimuse_pilt("cow.gif");
			uus_vastus = new Vastus();
			uus_vastus.setVastus_kasoige(false);
			uus_vastus.setVastusepilt("cow.gif");
			uus_vastus.setVastuse_text("suurus, mis väljendatakse protsentides ja saadakse miinimumpalga jagamisel keskmise palgaga");
			uus_kysimus.add_vastus(uus_vastus);

			uus_vastus = new Vastus();
			uus_vastus.setVastus_kasoige(false);
			uus_vastus.setVastusepilt("cow.gif");
			uus_vastus.setVastuse_text("kõikide töötute arv jagatud kõigi töötajate arvuga");
			uus_kysimus.add_vastus(uus_vastus);

			uus_vastus = new Vastus();
			uus_vastus.setVastus_kasoige(true);
			uus_vastus.setVastusepilt("dog.gif");
			uus_vastus.setVastuse_text("arvutatav inflatsioonimäära ja töötusemäära summana");
			uus_kysimus.add_vastus(uus_vastus);

			uus_vastus = new Vastus();
			uus_vastus.setVastus_kasoige(false);
			uus_vastus.setVastusepilt("question.gif");
			uus_vastus.setVastuse_text("suurus, mis näitab üldise hinnataseme tõusu");
			uus_kysimus.add_vastus(uus_vastus);

			add_kysimus(uus_kysimus);

			uus_kysimus = new Kysimus();
			uus_kysimus.set_kysimus("Millisel alltoodud meetodil on võimalik SKP välja arvutada?");
			uus_kysimus.setKysimuse_pilt("tank.jpg");
			uus_vastus = new Vastus();
			uus_vastus.setVastus_kasoige(false);
			uus_vastus.setVastusepilt("beaver.gif");
			uus_vastus.setVastuse_text("äkki kõik aasta jooksul toodetud toodete turuväärtuste summa ");
			uus_kysimus.add_vastus(uus_vastus);

			uus_vastus = new Vastus();
			uus_vastus.setVastusepilt("cow.gif");
			uus_vastus.setVastus_kasoige(true);
			uus_vastus.setVastuse_text("saadud tulu meetodil (palgad, üürid, intressid ja kasumid");
			uus_kysimus.add_vastus(uus_vastus);

			uus_vastus = new Vastus();
			uus_vastus.setVastusepilt("death.gif");
			uus_vastus.setVastus_kasoige(false);
			uus_vastus.setVastuse_text("elanike tarbimise alusel");
			uus_kysimus.add_vastus(uus_vastus);

			uus_vastus = new Vastus();
			uus_vastus.setVastusepilt("skunk.gif");
			uus_vastus.setVastus_kasoige(false);
			uus_vastus.setVastuse_text("liidetakse kõik tehtud investeeringud kokku");
			uus_kysimus.add_vastus(uus_vastus);

			add_kysimus(uus_kysimus);
		}
	}

	public Kysimused loeXML(String failinimi, Kysimused kyssad) {
		XMLDecoder decoder;
		try {
			FileInputStream stream = new FileInputStream(failinimi);
			decoder = new XMLDecoder(stream);
		} catch (Exception e) {

			System.out
					.println("Sorry, but an error occurred while trying to open the file:\n"
							+ e);
			return kyssad;
		}
		int kysimuste_arv = (Integer) decoder.readObject();
		for (int i = 0; i < kysimuste_arv; i++) {
			Kysimus c = (Kysimus) decoder.readObject();
			for (Vastus d : c.get_vastused()) {
				c.add_vastus(d);
				decoder.readObject();
			}
			kyssad.add_kysimus(c);
		}
		decoder.close();
		return kyssad;
	}

	public void randomizeAllAnswers() {
		for (int i = 0; i < this.kysimused.size(); i++) {
			this.kysimused.get(i).randomizeAnswers();
		}
	}

	public void xmlKirjutaja(Kysimused kyssad_data, String failinimi, boolean kas_kirjutan_yle) 
			throws WritingException {
		// FileOutputStream
		Writer writer = new java.io.StringWriter();
		XmlWriter xmlwriter = new XmlWriter(writer);
		try {
			writer.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
		} catch (IOException e) {
			e.printStackTrace();
		}
		xmlwriter.writeEntity("Test");
		xmlwriter.writeAttribute("teema", kyssad_data.getTeema());
		
		for (int i = 0; i < kyssad_data.get_Kysimused().size(); i++) {
			try {
				writer.append("\n");
			} catch (IOException e) {
				e.printStackTrace();
			}
			xmlwriter.writeEntity("Question");
			xmlwriter.writeEntity("Kysimus");
			Kysimus uus_kysimus = kyssad_data.get_Kysimused().get(i);
			xmlwriter.writeAttribute("kyssa_pilt", uus_kysimus.getKysimuse_pilt());
			xmlwriter.writeText(uus_kysimus.get_kysimus());
			xmlwriter.endEntity();
			try {
				writer.append("\n");
			} catch (IOException e) {
				e.printStackTrace();
			}
			for (int z = 0; z < uus_kysimus.get_vastused().size(); z++) {
				Vastus uus_vastus = uus_kysimus.get_vastused().get(z);
				try {
					writer.append("\t");
				} catch (IOException e) {
					e.printStackTrace();
				}
				xmlwriter.writeEntity("Vastus");
				if (uus_vastus.getVastus_kasoige())
					xmlwriter.writeAttribute("kas_oige", "true");
				else
					xmlwriter.writeAttribute("kas_oige", "false");
				xmlwriter.writeAttribute("vastuse_pilt", uus_vastus.getVastusepilt());
				xmlwriter.writeText(uus_vastus.getVastuse_text());
				xmlwriter.endEntity();
				try {
					writer.append("\n");
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			xmlwriter.endEntity();
			try {
				writer.append("\n");
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		xmlwriter.endEntity();
		xmlwriter.close();
		if (kas_kirjutan_yle)
			Failihaldur.kustutafail(failinimi);
		try {
			BufferedWriter out = new BufferedWriter(new OutputStreamWriter(
					new FileOutputStream(failinimi), "UTF8"));
			out.write(writer.toString());
			out.close();
		} catch (Exception e) {// Catch exception if any
			System.err.println("Error: " + e.getMessage());
		}
	}

	public Kysimused loeXML_data(String failinimi, Kysimused kyssad) {
		FileInputStream stream;
		try {
			stream = new FileInputStream(failinimi);
		} catch (FileNotFoundException e1) {
			System.out.println("ERROR:  Missing file.\n\n" + e1);
			return kyssad;
		}

		org.w3c.dom.Document xmldoc;
		try {
			DocumentBuilder docReader = DocumentBuilderFactory.newInstance()
					.newDocumentBuilder();
			xmldoc = docReader.parse(new InputSource(stream));
		} catch (Exception e) {
			System.out.println("ERROR:  The input is not well-formed XML.\n\n" + e);
			return kyssad;
		}

		org.w3c.dom.Element rootElement = xmldoc.getDocumentElement();
		kyssad.setTeema(rootElement.getAttribute("teema"));

		NodeList nodes = rootElement.getChildNodes();

		for (int i = 0; i < nodes.getLength(); i++) {

			if (nodes.item(i) instanceof org.w3c.dom.Element) {
				org.w3c.dom.Element element = (org.w3c.dom.Element) nodes.item(i);
				if (element.getTagName().equals("Question")) {
					Kysimus uus_kysimus = new Kysimus();
					NodeList questionNodes = element.getChildNodes();

					for (int j = 0; j < questionNodes.getLength(); j++) {
						if (questionNodes.item(j) instanceof org.w3c.dom.Element) {
							org.w3c.dom.Element questionElement = (org.w3c.dom.Element) questionNodes.item(j);

							if (questionElement.getTagName().equals("Kysimus")) { 
								uus_kysimus.setKysimuse_pilt(questionElement.getAttribute("kyssa_pilt"));
								uus_kysimus.set_kysimus(questionElement.getTextContent());
							}
							if (questionElement.getTagName().equals("Vastus")) { 
								Vastus uus_vastus = new Vastus();
								uus_vastus.setVastusepilt(questionElement.getAttribute("vastuse_pilt"));
								if (questionElement.getAttribute("kas_oige").equals("true")) {
									uus_vastus.setVastus_kasoige(true);
								} else {
									uus_vastus.setVastus_kasoige(false);
								}

								uus_vastus.setVastuse_text(questionElement.getTextContent());
								uus_kysimus.add_vastus(uus_vastus);
							}
						}
					} // end for

					kyssad.add_kysimus(uus_kysimus);

				} // end if (element.getTagName().equals("Question")) {

			}

		} // end for for (int i = 0; i < nodes.getLength(); i++) {

		return kyssad;

	} // end readXML

	public void add_kysimus(Kysimus kysimus_new) {

		kysimused.add(kysimus_new);

	}

	public Kysimused laeKyssadBlackboardist(String failinimi, Kysimused kysimuste_data) {
		File f = new File(failinimi);
		try {
			BufferedReader in = new BufferedReader(new FileReader(f));
			String line;
			boolean otsime_number_rea_alguses = false;
			boolean otsime_kysimuse_tyelist_kasutatavat_rida = false;
			boolean otsime_vastuseid = false;
			boolean esimene_kys_edukas = false;
			int reacounter = 0;
			Kysimus kyssa = new Kysimus();

			while ((line = in.readLine()) != null) {
				if (line.length() == 0) {
					line = "  ";
				}
				if (line.contains("Score")) {
					if (esimene_kys_edukas == true) {
						kysimuste_data.add_kysimus(kyssa);
					}
					otsime_number_rea_alguses = true;
					otsime_kysimuse_tyelist_kasutatavat_rida = false;
					otsime_vastuseid = false;
				} else {
					if (otsime_number_rea_alguses == true) {
						if (Character.isDigit(line.charAt(0))) {

							otsime_number_rea_alguses = false;
							otsime_kysimuse_tyelist_kasutatavat_rida = true;
							reacounter = 0;
						}
					} else {
						if (otsime_kysimuse_tyelist_kasutatavat_rida == true) {
							reacounter++;
							if (reacounter == 2) { // siin peaksime olema saanud käsimuse kätte
								kyssa = new Kysimus();
								esimene_kys_edukas = true;
								kyssa.set_kysimus(line);
								otsime_kysimuse_tyelist_kasutatavat_rida = false;
								otsime_vastuseid = true;
							}
						} else {
							if (otsime_vastuseid == true) {
								if (Character.isUpperCase(line.charAt(0))
										|| Character.isUpperCase(line.charAt(1))) {
									Vastus vastus = new Vastus();
									boolean vastus_kaes = false;
									int tabulaatori_counter = 0;
									String supervastus = "";
									for (int i = 0; i < line.length(); i++) {
										if (line.charAt(i) == '\t') {
											if (tabulaatori_counter > 0) {
												if (!vastus_kaes) {
													vastus.setVastuse_text(supervastus);
													vastus_kaes = true;
												}
											}
											tabulaatori_counter++;
										} else {
											if (tabulaatori_counter == 1) {
												supervastus = supervastus + line.charAt(i);
											}
										}
										if (vastus_kaes == true) {
											if (line.charAt(i) == '%') {
												vastus.setVastus_kasoige(true);
											}
										}
									} // end for 
									vastus.setVastuse_text(supervastus);
									kyssa.add_vastus(vastus);
								}
							} // end if if (otsime_vastuseid == true) {
						}
					} // end else if (otsinumbrit_rea_alguses == true) {
				} // end else if (line.contains("Score")){
			}
		} catch (Exception e) {
			System.out.println("Error: " + e.getMessage());
		} // laeb s6nad massiivi END
		return kysimuste_data;
	}

	public void setTeema(String teema) {
		this.teema = teema;
	}

	public String getTeema() {
		return teema;
	}

}
